; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx900 -verify-machineinstrs < %s | FileCheck -enable-var-scope -check-prefix=GCN %s

define i32 @range_metadata_sext_i8_signed_range_i32(ptr addrspace(1) %ptr) {
; GCN-LABEL: range_metadata_sext_i8_signed_range_i32:
; GCN:       ; %bb.0:
; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GCN-NEXT:    global_load_dword v0, v[0:1], off glc
; GCN-NEXT:    s_waitcnt vmcnt(0)
; GCN-NEXT:    s_setpc_b64 s[30:31]
  %val = load volatile i32, ptr addrspace(1) %ptr, align 4, !range !0 ; [-127, 128)
  %shl = shl i32 %val, 24
  %ashr = ashr i32 %shl, 24
  ret i32 %ashr
}

define i32 @range_metadata_sext_upper_range_limited_i32(ptr addrspace(1) %ptr) {
; GCN-LABEL: range_metadata_sext_upper_range_limited_i32:
; GCN:       ; %bb.0:
; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GCN-NEXT:    global_load_dword v0, v[0:1], off glc
; GCN-NEXT:    s_waitcnt vmcnt(0)
; GCN-NEXT:    v_bfe_i32 v0, v0, 0, 8
; GCN-NEXT:    s_setpc_b64 s[30:31]
  %val = load volatile i32, ptr addrspace(1) %ptr, align 4, !range !1 ; [-127, 256)
  %shl = shl i32 %val, 24
  %ashr = ashr i32 %shl, 24
  ret i32 %ashr
}

define i32 @range_metadata_sext_lower_range_limited_i32(ptr addrspace(1) %ptr) {
; GCN-LABEL: range_metadata_sext_lower_range_limited_i32:
; GCN:       ; %bb.0:
; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GCN-NEXT:    global_load_dword v0, v[0:1], off glc
; GCN-NEXT:    s_waitcnt vmcnt(0)
; GCN-NEXT:    v_bfe_i32 v0, v0, 0, 8
; GCN-NEXT:    s_setpc_b64 s[30:31]
  %val = load volatile i32, ptr addrspace(1) %ptr, align 4, !range !2 ; [-255, 128)
  %shl = shl i32 %val, 24
  %ashr = ashr i32 %shl, 24
  ret i32 %ashr
}

define i32 @range_metadata_sext_i8_neg_neg_range_i32(ptr addrspace(1) %ptr) {
; GCN-LABEL: range_metadata_sext_i8_neg_neg_range_i32:
; GCN:       ; %bb.0:
; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GCN-NEXT:    global_load_dword v0, v[0:1], off glc
; GCN-NEXT:    s_waitcnt vmcnt(0)
; GCN-NEXT:    v_and_b32_e32 v0, 63, v0
; GCN-NEXT:    s_setpc_b64 s[30:31]
  %val = load volatile i32, ptr addrspace(1) %ptr, align 4, !range !3
  %shl = shl i32 %val, 25
  %ashr = ashr i32 %shl, 25
  ret i32 %ashr
}

define i32 @range_metadata_sextload_i8_signed_range_i4_i32(ptr addrspace(1) %ptr) {
; GCN-LABEL: range_metadata_sextload_i8_signed_range_i4_i32:
; GCN:       ; %bb.0:
; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GCN-NEXT:    global_load_sbyte v0, v[0:1], off glc
; GCN-NEXT:    s_waitcnt vmcnt(0)
; GCN-NEXT:    s_setpc_b64 s[30:31]
  %load = load volatile i8, ptr addrspace(1) %ptr, align 1, !range !4
  %shl = shl i8 %load, 3
  %ashr = ashr i8 %shl, 3
  %ext = sext i8 %ashr to i32
  ret i32 %ext
}

define i25 @range_metadata_sext_i8_signed_range_i25(ptr addrspace(1) %ptr) {
; GCN-LABEL: range_metadata_sext_i8_signed_range_i25:
; GCN:       ; %bb.0:
; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GCN-NEXT:    global_load_dword v0, v[0:1], off glc
; GCN-NEXT:    s_waitcnt vmcnt(0)
; GCN-NEXT:    v_bfe_i32 v0, v0, 0, 2
; GCN-NEXT:    s_setpc_b64 s[30:31]
  %val = load volatile i25, ptr addrspace(1) %ptr, align 4, !range !5
  %shl = shl i25 %val, 23
  %ashr = ashr i25 %shl, 23
  ret i25 %ashr
}

define i32 @range_metadata_i32_neg1_to_1(ptr addrspace(1) %ptr) {
; GCN-LABEL: range_metadata_i32_neg1_to_1:
; GCN:       ; %bb.0:
; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GCN-NEXT:    global_load_dword v0, v[0:1], off glc
; GCN-NEXT:    s_waitcnt vmcnt(0)
; GCN-NEXT:    s_setpc_b64 s[30:31]
  %val = load volatile i32, ptr addrspace(1) %ptr, align 4, !range !6
  %shl = shl i32 %val, 31
  %ashr = ashr i32 %shl, 31
  ret i32 %ashr
}

define i64 @range_metadata_sext_i8_signed_range_i64(ptr addrspace(1) %ptr) {
; GCN-LABEL: range_metadata_sext_i8_signed_range_i64:
; GCN:       ; %bb.0:
; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GCN-NEXT:    global_load_dwordx2 v[0:1], v[0:1], off glc
; GCN-NEXT:    s_waitcnt vmcnt(0)
; GCN-NEXT:    v_lshlrev_b32_e32 v1, 23, v0
; GCN-NEXT:    v_ashrrev_i64 v[0:1], 55, v[0:1]
; GCN-NEXT:    s_setpc_b64 s[30:31]
  %val = load volatile i64, ptr addrspace(1) %ptr, align 4, !range !7
  %shl = shl i64 %val, 55
  %ashr = ashr i64 %shl, 55
  ret i64 %ashr
}

define i64 @range_metadata_sext_i32_signed_range_i64(ptr addrspace(1) %ptr) {
; GCN-LABEL: range_metadata_sext_i32_signed_range_i64:
; GCN:       ; %bb.0:
; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GCN-NEXT:    global_load_dwordx2 v[0:1], v[0:1], off glc
; GCN-NEXT:    s_waitcnt vmcnt(0)
; GCN-NEXT:    s_setpc_b64 s[30:31]
  %val = load volatile i64, ptr addrspace(1) %ptr, align 4, !range !7
  %shl = shl i64 %val, 31
  %ashr = ashr i64 %shl, 31
  ret i64 %ashr
}

define i64 @range_metadata_sext_i33_signed_range_i64(ptr addrspace(1) %ptr) {
; GCN-LABEL: range_metadata_sext_i33_signed_range_i64:
; GCN:       ; %bb.0:
; GCN-NEXT:    s_waitcnt vmcnt(0) expcnt(0) lgkmcnt(0)
; GCN-NEXT:    global_load_dwordx2 v[0:1], v[0:1], off glc
; GCN-NEXT:    s_waitcnt vmcnt(0)
; GCN-NEXT:    s_setpc_b64 s[30:31]
  %val = load volatile i64, ptr addrspace(1) %ptr, align 4, !range !8
  %shl = shl i64 %val, 30
  %ashr = ashr i64 %shl, 30
  ret i64 %ashr
}

!0 = !{i32 -127, i32 128}
!1 = !{i32 -127, i32 256}
!2 = !{i32 -255, i32 128}
!3 = !{i32 -127, i32 -64}
!4 = !{i8 -15, i8 16}
!5 = !{i25 -127, i25 128}
!6 = !{i32 -1, i32 1}
!7 = !{i64 -4294967295, i64 4294967296}
!8 = !{i64 -8589934591, i64 8589934592}
